home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
dbdoc.zip
/
DBFDOC.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-08
|
8KB
|
196 lines
/* Somerset Data Systems, Inc. (908) 766-5845 */
/* Version 1.2 April 6, 1991 */
/* Programmer: Jay Parsons */
/* Note: */
/****************************************************************************/
#include <ctype.h>
#include <stdio.h>
#include <string.h>
/****************************************************************************/
/* definitions */
/****************************************************************************/
/**** **** values **** ****/
#define HEADLEN 32 /* sizeof ( mainhead or thisfield ) */
#define MEMOLEN 10 /* length of memo field in .dbf */
#define DBFTYPE 3 /* value of bits 0 and 1 if .dbf */
#define EOH 0x0D /* end-of-header marker in .dbf file */
/**** **** data types **** ****/
typedef unsigned long ulong; /* just an abbreviation */
extern char file_name[], message[], tempbuff[];
/* first 32 bytes of a .dbf file */
typedef struct
{
unsigned dbf:2; /* both 1 for dBASE III or IV .dbf */
unsigned :1;
unsigned db4dbt:1; /* 1 if a dBASE IV-type .dbt exists */
unsigned :3;
unsigned anydbt:1; /* 1 if any .dbt exists */
char filedate[3]; /* date, YYMMDD, binary. YY=year-1900 */
ulong records; /* records in the file */
unsigned headerlen; /* bytes in the header */
unsigned recordlen; /* bytes in a record */
int rsrvd1;
char incompleteflag; /* 01 if incomplete, else 00 */
char encryptflag; /* 01 if encrypted, else 00 */
char rsrvd2[12]; /* for LAN use */
char mdxflag; /* 01 if production .mdx, else 00 */
char rsrvd3[3];
} dbfheader;
/* field descriptor of a .dbf file */
typedef struct
{
char fname[11]; /* field name, in capitals, null filled*/
char ftype; /* field type, C, D, F, L, M or N */
char rsrvd4[4]; /* used in memvars, not in files. */
unsigned char flength; /* field length */
unsigned char decimals; /* number of decimal places */
int rsrvd5;
char workarea;
char rsrvd6[10];
char mdxfield; /* 01 if tag field in production .mdx */
} descriptor;
/**** **** function prototypes **** ****/
int dbfdoc ( char *filespec );
FILE * dbfopen ( char *filespec, dbfheader *buffptr );
int dbfield_off ( FILE *file, char *ourfield, descriptor *buf );
/****************************************************************************/
/* dbfdoc */
/* Principal routine of this module. Reads and returns the structure */
/* of the file of the name passed. */
/* Returns: */
/* 0 if successful, 1 if any error occurs. */
/* */
/* This routine creates two buffers for .dbf header information. */
/* It then calls dbfopen() to open the file, test for it being a .dbf */
/* type and place the main header in its buffer. */
/****************************************************************************/
int dbfdoc ( char *file_name )
{
FILE *dbffile;
dbfheader mainhead;
descriptor thisfield;
int field, fields, err;
/* open file and check for .dbf type */
/* must close it if opened, else not */
if ( ( dbffile = dbfopen( file_name, &mainhead ) ) == NULL )
{
sprintf( message, "Can't open file %s.", file_name );
return 1;
}
sprintf( message, "Structure of %s", strupr( file_name ) );
printit( 0 );
sprintf( message, "%d records, last changed ", ( int ) mainhead.records );
sprintf ( tempbuff, "%02d/", mainhead.filedate[1] );
strcat( message, tempbuff );
sprintf ( tempbuff, "%02d/", mainhead.filedate[2] );
strcat( message, tempbuff );
sprintf ( tempbuff, "%d", mainhead.filedate[0] + 1900 );
strcat( message, tempbuff );
printit( 0 );
strcpy( message, "Field Type Len Dec" );
printit( 0 );
/* do it field by field. We are at byte 32 of file */
fields = ( mainhead.headerlen - 33 ) / 32;
for ( field = 1; field <= fields; field++ )
{
err = fread( &thisfield, HEADLEN, 1, dbffile ) - 1;
if ( err )
break;
sprintf( message, "%-11s", thisfield.fname );
strcat( message, " " );
*tempbuff = thisfield.ftype;
*( tempbuff + 1 ) = '\0';
strcat( message, tempbuff );
sprintf( tempbuff, " %3d %2d", thisfield.flength, thisfield.decimals );
strcat( message, tempbuff );
printit( 0 );
}
fclose( dbffile );
return err;
}
/****************************************************************************/
/* dbfopen */
/* Routine to open .dbf file. */
/* Parameters: */
/* char *filespec -- pointer to spec of file to open */
/* dbfheader *buf -- pointer to dbfheader structure */
/* Returns: */
/* Pointer to C file control structure (to NULL if error) */
/* Side effects: */
/* Opens file and moves pointer to byte 32; fills buffer at buf with */
/* first 32 bytes of file. Closes file on error. */
/****************************************************************************/
FILE *dbfopen( char *filespec, dbfheader *buf )
{
FILE *file;
char *endmark;
if ( ( file = fopen( filespec, "rb" ) ) == NULL )
return NULL; /* can't open .dbf */
/* read the first 32 bytes into buffer */
if ( fread( buf, HEADLEN, 1, file ) != 1 )
{
fclose( file );
return NULL; /* can't read 32 bytes */
}
/* check first byte to be sure .dbf type */
if ( buf->dbf != DBFTYPE )
{
fclose( file );
return NULL; /* not a .dbf file */
}
/* check last byte of header */
if ( fseek( file, buf->headerlen - 1, SEEK_SET ) != 0 )
{
fclose( file );
return NULL; /* header corrupted */
}
if ( fread( endmark, 1, 1, file ) != 1 )
{
fclose( file );
return NULL; /* can't read end of header */
}
if ( *endmark != EOH )
{
fclose( file );
return NULL; /* no 0Dh at end of header */
}
fseek( file, HEADLEN, SEEK_SET );
return file;
}
/* EOF */